import path from "path"import os from "os"
<template lang="pug">
  master-layout
    div.timer(v-if="examTimer" slot="header" :class="timerClass")
      div.timer-mn
        span.mit 剩余时间：
        span.mxt {{examTimer}}
    div.question-w(slot="main")
      div.tip
        | 绝密
        span(v-on:dblclick.ctrl.alt="handlerClickBeginOpenProject") ★
        | 启用前
      div.ctx
        div.tt 2020年7月吉林省高等教育自学考试
        div.ds
          div.cnt
            | {{examInfo.subject}}　试卷（课程代码{{examInfo.subjectVal}}）
            br
            b 本试卷满分{{examInfo.perScore}}分；考试时间{{examInfo.duration}}分钟。
            br
            | 考生应按照提交要求保存，未按要求提交的一律视作无效。
          div.sl
            div.name 姓名:
              span {{stuInfo.userName}}
            div.card 身份证号:
              span {{stuInfo.idCards}}
            div.card 考试编号:
              span {{stuInfo.examId}}
      div.main
        div.upload-w
          el-upload.upload-demo(:auto-upload="false" action=""
            :accept="accept"
            :multiple="true"
            :limit="uploadFileMaxLimit"
            list-type="text"
            :on-exceed="handleExceed"
            :on-change="handleChange"
            :on-remove="handleRemove"
            :on-preview="handlePreview")
            div.exam-btn.app.active(v-show="isStumit" slot="trigger" type="primary") 选取文件
            div.exam-btn.app(v-show="!isStumit" type="primary") 选取文件
            div.exam-btn.stumit(v-bind:class="isStumit?'active':''" v-on:click="handleUploadFileList")
              span(v-if="ts") {{ts}}
              | 交卷
            div.el-upload__tip(slot="tip")
              div.tip-txt
                i.el-icon-warning
                |  请将文件大小控制在 {{fileCountMaxSize}}M 以内，且文件名不能重复。
                span(v-if="this.uploadFileList.length") 当前已选择 {{this.uploadFileList.length}} 个文件，
                  template(v-if="checkFileSize") 总大小符合标准。
                  template(v-else) 总大小超过 {{fileCountMaxSize}}M，不能上传。
        div.c
          div.tt {{examInfo.title}}
          div.c-b {{examInfo.stem}}
          div.c-c
            div.tt.c-c-1 提交要求：
            div.c-c-2
              template(v-for="(item,idx) in examInfo.answerConstraint")
                template(v-if="item.length>0")
                  | {{item}}。
                  br
</template>

<script type="text/ecmascript-6">
  import MasterLayout from '../layout/Master'
  import {checkFolder, countdown, dateFormat} from '../config/utils'
  import fs from 'fs'
  import zipdir from 'zip-dir'
  import nodeCmd from 'node-cmd'
  import Ftp from 'ftp'
  import Electrom from 'electron'
  import {mapGetters} from 'vuex'

  export default {
    components: {
      MasterLayout
    },
    data() {
      return {
        btnText: '开始答题',
        isActive: true,
        totalMinute: 0, // 考试总时长
        minSubmitDate: 3, // 最小提交时间分钟
        examingTimer: 0,
        isBegin: false,
        examData: {},
        examInfo: {},
        m: {},
        m2: {},
        kemu: [
          {
            title: '角色动画设计（二）',
            fileName: 'demo.max'
          },
          {
            title: '三维专业软件3DMAX',
            fileName: 'demo.max'
          },
          {
            title: '数码造型设计基础（二）',
            fileName: 'demo.psd'
          },
          {
            title: '数码造型基础（二）',
            fileName: 'demo.psd'
          },
          {
            title: '游戏材质与渲染',
            fileName: 'demo.max'
          },
          {
            title: '游戏画面设计（二）',
            fileName: 'demo.psd'
          },
          {
            title: '游戏引擎应用工程文件',
            fileName: 'demo.unitypackage'
          }
        ],
        km: '',
        stuInfo: {},
        mtCheckTime: null,
        examingCheckTime: '/camel/rest/examings/checktime',
        zipFileName: 'examFile.zip',
        uploadFileName: '',
        isStumit: false,
        quesIds: '',
        demoFileName: 'demo',
        demoFileExtName: '',
        currentServerTime: null, // 服务器时间
        examBeginTime: null, // 考试开始时间,
        examEndTime: null, // 考试结束时间,
        accept: 'image/gif,image/jpeg,image/png',
        baseSize: 1048576,
        fileCountMaxSize: 5,
        uploadFileList: [],
        uploadFilePath: `${__static}\\uploadFiles\\`,
        uploadFileTip: '',
        uploadFileMaxLimit: 4,
        chkCnt: 0
      }
    },
    mounted() {
      // setTimeout(() => {
      //   this.isStumit = true
      //   // this.accept = 'video/mp4'
      //   // this.uploadFileTip = '只能上传 mp4 文件，且文件大小不超过 4M。'
      // }, 3000)
      this.isAutoSubmit = false
      this.uploadFileTip = `gif、jpeg、png`
      this._closeCheckTime()
      let _stuInfo = this.$KalixCatch.get('STUDENT_INFO')
      if (_stuInfo) {
        this.stuInfo = JSON.parse(_stuInfo)
        this.examBeginTime = this.stuInfo.examStart
        this.examEndTime = this.stuInfo.examEndTime
        this.totalMinute = this.stuInfo.duration
        this.quesIds = this.stuInfo.quesIds
        this.km = this.stuInfo.subject
        console.log('km:', this.km)
        if (this.km === '角色动画设计（一）') {
          this.accept = 'video/avi'
          // this.fileCountMaxSize = 5
          this.uploadFileTip = `avi`
        }
        this.getPaper()
        this._checkTime()
        this.$http.request({
          method: 'put',
          url: '/camel/rest/examings/updateexamstart',
          data: {
            userId: this.stuInfo.stuId,
            examId: this.stuInfo.examId
          }
        }).then(res => {
          console.log('res', res)
        })
      }
    },
    methods: {
      handleChange(file, fileList) {
        this.uploadFileList = fileList
        // console.log('handleChange', file, fileList)
        // console.log('handleChange', file.size / this.baseSize)
      },
      handleExceed(file, fileList) {
        this.$alert(`上传文件数量不能超过 ${this.uploadFileMaxLimit} 个。`, '消息')
      },
      handlePreview(file) {
        // console.log(file)
        console.log('handlePreview', file)
      },
      handleRemove(file, fileList) {
        console.log('handleRemove', file, fileList)
        this.uploadFileList = fileList
      },
      /**
       * 提交文件
       */
      handleUploadFileList() {
        if (!this.fileListComplete) {
          this.$msgbox({
            title: '系统提示',
            type: 'error',
            message: `<p>由于你没有选择任何文件，提交试卷后将会是 0 分。是否继续？</p>`,
            dangerouslyUseHTMLString: true,
            showCancelButton: true,
            confirmButtonText: '确定',
            cancelButtonText: '取消'
          }).then(action => {
            console.log(action)
            this.handlerClickSubmitExam()
          }).catch(() => {
            // console.log(error)
          })
          return false
        }
        this.$msgbox({
          title: '系统提示',
          type: 'info ',
          message: `<p>已准备${this.uploadFileList.length}个文件，是否提交？</p>`,
          dangerouslyUseHTMLString: true,
          showCancelButton: true,
          confirmButtonText: '确定',
          cancelButtonText: '取消'
        }).then(action => {
          const filePath = []
          let countSize = 0
          let tempFileArray = []
          let cnt = 0
          const FILE_TYPE = this.accept.split(',')
          this.uploadFileList.forEach(e => {
            const fileRaw = e.raw
            // 统计上传文件
            filePath.push({
              source: fileRaw.path,
              target: this.uploadFilePath + e.name
            })
            // 统计文件大小
            countSize += fileRaw.size
            // 统计文件名
            tempFileArray.push(e.name)
            // 统计文件类型
            let idx = FILE_TYPE.findIndex((fe) => {
              return fe === fileRaw.type
            })
            if (idx === -1) {
              cnt += 1
            }
          })
          // 检查文件格式
          if (cnt > 0) {
            // this.$alert('文件格式不符合要求。', '消息')
            // return false
          }
          // 检查文件名重复
          let tempFileArrayB = Array.from(new Set(tempFileArray))
          let flag = tempFileArray.length === tempFileArrayB.length
          if (!flag) {
            this.$alert('文件名重复，请重新选择！', '消息')
            return false
          }
          // 检查文件大小
          if (countSize > this.uploadFileMaxSize) {
            this.$alert(`全部文件总大小不能超过 ${this.fileCountMaxSize}M ！请重新选择文件。`, '消息')
            return false
          }
          this.delDir(this.uploadFilePath).then(() => {
            fs.mkdirSync(this.uploadFilePath)
            filePath.forEach(fileItem => {
              fs.copyFileSync(fileItem.source, fileItem.target)
            })
            this.handlerClickSubmitExam()
          })
        }).catch(() => {
          // console.log(error)
        })
      },
      /**
       * 打开素材文件夹
       */
      handlerClickBeginOpenMaterialFolder() {
        nodeCmd.get(`start ${window.KalixConfig.materialFolder + this.km}`, err => {
          console.log('打开素材文件夹 err', err)
        })
      },
      /**
       * 打开软件
       */
      handlerClickBeginOpenSoftware() {
        let fileExt = this.demoFileExtName.indexOf('.') > -1 ? this.demoFileExtName : `.${this.demoFileExtName}`
        let projectFolder = `${__static}\\project\\${this.quesIds}\\${this.demoFileName}${fileExt}`
        if (fileExt.indexOf(`unity`) > -1) {
          // if (this.quesIds + '' === '1028824') {
          // if (this.quesIds + '' === '1028821') {
          projectFolder = `${__static}\\project\\${this.quesIds}\\Assets\\kaoshi.unity`
        }
        nodeCmd.get(projectFolder, (err) => {
          if (err) {
            throw err
          }
        })
      },
      /**
       * 打开工程文件夹
       */
      handlerClickBeginOpenProject() {
        nodeCmd.get(`start ${__static}\\project\\${this.quesIds}`, err => {
          console.log('打开素材文件夹 err', err)
        })
      },
      /**
       * 选择文件
       */
      async handleChangeSetFile() {
        const uploadFile = `${__static}\\uploadFiles\\`
        this.delDir(uploadFile).then(() => {
          fs.mkdirSync(uploadFile)
          let iptSubmitFiles = document.querySelector('#iptSubmitFiles')
          let countSize = 0
          if (iptSubmitFiles && iptSubmitFiles.files.length) {
            for (let i = 0; i < iptSubmitFiles.files.length; i++) {
              const tempFileObj = iptSubmitFiles.files[i]
              countSize += tempFileObj.size
              fs.copyFileSync(tempFileObj.path, uploadFile + tempFileObj.name)
            }
          }
          if (countSize > this.fileCountMaxSize) {
            this.$alert(`全部文件总大小不能超过 ${this.fileCountMaxSize}M ！请重新选择文件。`, '消息')
          } else {
            this.handlerClickSubmitExam()
          }
        })
      },
      /**
       * 提交试卷
       */
      async handlerClickSubmitExam() {
        // this.isStumit = true
        if (this.isStumit) {
          let _path = `${this.uploadFilePath}\\${this.zipFileName}`
          let err = await checkFolder(_path)
          if (!err) {
            this.compressAndUpload()
          } else {
            fs.unlink(_path, (err) => {
              if (err) {
                console.log('unlink err', err)
              } else {
                this.compressAndUpload()
              }
            })
          }
        } else {
          this.$KalixMessage.error('还没到最快交卷时间！')
        }
      },
      delDir(path) {
        return new Promise(resolve => {
          let files = []
          if (fs.existsSync(path)) {
            files = fs.readdirSync(path)
            files.forEach((file, index) => {
              let curPath = path + '/' + file
              if (fs.statSync(curPath).isDirectory()) {
                this.delDir(curPath) // 递归删除文件夹
              } else {
                fs.unlinkSync(curPath) // 删除文件
              }
            })
            fs.rmdirSync(path)
          }
          resolve()
        })
      },
      // 压缩文件并上传
      async compressAndUpload() {
        this.uploadFileName = `${this.stuInfo.loginName}-${this.stuInfo.examId}.zip`
        const l1 = this.loadingTools(`正在准备文件`)
        const cErr = await this.compressFolder()
        l1.close()
        if (cErr) {
          return
        }
        const l3 = this.loadingTools(`正在上传文件`)
        await this._uploadFile()
        l3.close()
        const l2 = this.loadingTools(`正在准备数据`)
        await this._submitData()
        l2.close()
        clearInterval(this._mt)
        clearTimeout(window.mtAutoCloseExam)
        this.$alert('交卷成功，文件已上传！点击确定返回登录界面。', '消息', {
          callback: action => {
            this.$http.get('/logout')
            this.$router.replace('/')
          }
        })
      },
      _uploadFile() {
        return new Promise(resolve => {
          let c = new Ftp()
          c.on('ready', () => {
            c.put(`${this.uploadFilePath}\\${this.zipFileName}`, this.uploadFileName, err => {
              if (err) {
                // console.log('_uploadFile err', err)
                throw err
              }
              c.end()
              resolve()
            })
          })
          c.connect({
            host: window.KalixConfig.ftphost,
            user: window.KalixConfig.ftpuser,
            password: window.KalixConfig.ftppwd
          })
        })
      },
      ftpFileUpload(sourceFile, targetFile) {
        return new Promise(resolve => {
          let c = new Ftp()
          c.on('ready', () => {
            c.put(sourceFile, targetFile, err => {
              if (err) {
                // console.log('_uploadFile err', err)
                throw err
              }
              c.end()
              resolve()
            })
          })
          c.connect({
            host: window.KalixConfig.ftphost,
            user: window.KalixConfig.ftpuser,
            password: window.KalixConfig.ftppwd
          })
        })
      },
      /**
       * 提交考卷信息
       */
      _submitData(callBack) {
        return new Promise(async resolve => {
          this._closeCheckTime()
          let quesList = [{
            title: this.examInfo.title,
            titleNum: this.examInfo.titleNum,
            perScore: this.examInfo.perScore,
            quesid: this.examInfo.quesid,
            quesNum: 1,
            quesType: this.examInfo.quesType,
            subType: this.examInfo.subType,
            answer: this.uploadFileName
          }]
          let postData = {
            examId: this.stuInfo.examId,
            paperId: this.stuInfo.paperId,
            userId: this.stuInfo.stuId,
            quesList
          }
          // console.log('交卷', postData)
          let res = await this.$http.post(this.$KalixGlobalConfig.ExamingCommitURL, postData)
          if (res && res.data && res.data.success) {
          } else {
            this.$KalixMessage.error('登录超时')
          }
          resolve()
        })
      },
      /**
       * 压缩文件
       */
      compressFolder() {
        return new Promise(resolve => {
//                    let _path = `D:\\${window.customCourse || this.km}\\`
          let _path = `${__static}\\uploadFiles\\`
          let files = fs.readdirSync(_path)
          this.isAutoSubmit = true
          if (this.isAutoSubmit) {
            if (files.length === 0) {
              fs.mkdirSync(`${_path}${this.stuInfo.examId}`)
            }
            zipdir(_path, {saveTo: `${_path + this.zipFileName}`}, (err, buffer) => {
              resolve(err)
            })
          } else if (files.length) {
            zipdir(_path, {saveTo: `${_path + this.zipFileName}`}, (err, buffer) => {
              resolve(err)
            })
          } else {
            this.$alert(`无法提交！因为没有选取文件。`, '系统提示')
            // this.$msgbox({
            //   title: '系统提示',
            //   type: 'error',
            //   message: `<h3>无法提交！</h3><p>因为没有文件。</p>`,
            //   dangerouslyUseHTMLString: true,
            //   showCancelButton: true,
            //   confirmButtonText: '确定',
            //   cancelButtonText: '打开文件夹'
            // }).then(action => {
            //   console.log(action)
            // }).catch(error => {
            //   nodeCmd.get(`start ${_path}`, err => {
            //     console.log('打开素材文件夹 err', err)
            //     console.log('打开素材文件夹 error', error)
            //   })
            // })
            resolve(new Error(`${_path}没有文件`))
          }
        })
      },
      /**
       * 生成试卷
       */
      async getPaper() {
        let {status, data: {quesList, subject, subjectVal, duration, examMinTime, durationTime}} = await this.$http.get(this.$KalixGlobalConfig.ExamingPaperURL, {
          params: {
            examId: this.stuInfo.examId,
            paperId: this.stuInfo.paperId
          }
        })
        if (status === 200) {
          this.examInfo = {subject, subjectVal, duration, examMinTime}
          this.minSubmitDate = examMinTime
          this.durationTime = durationTime
          this.examData = quesList
          if (quesList.length && quesList[0].question && quesList[0].question.length) {
            this.examInfo.stem = quesList[0].question[0].stem
            this.examInfo.title = quesList[0].title
            this.examInfo.titleNum = quesList[0].titleNum
            this.examInfo.perScore = quesList[0].perScore
            this.demoFileExtName = quesList[0].question[0].scoreStandard
            let _paperBean = quesList[0].question[0].paperBean
            this.examInfo.quesid = _paperBean.quesid
            this.examInfo.quesType = _paperBean.quesType
            this.examInfo.subType = _paperBean.subType
            let _answerConstraint = quesList[0].question[0].answerConstraint
            this.examInfo.answerConstraint = _answerConstraint.split('。')
          }
          this.beginTimer()
        }
      },
      /**
       * 开始计时
       * @private
       */
      beginTimer() {
        this.getServerTime()
      },
      async getServerTime() {
        let {status, data} = await this.$http.get('/camel/rest/currentDates')
        if (status === 200) {
          this.currentServerTime = (new Date(data)).getTime()
          this._chkSibmit()
          this._examCountdown()
        }
      },
      /**
       * 考试时间倒计时
       * @private
       */
      _examCountdown() {
        let t1 = this.examEndTime // 考试结束时间
        let tt = t1 - this.currentServerTime
        // console.log('this.currentServerTime:', this.currentServerTime)
        // console.log('this.examEndTime:', this.examEndTime)
        // console.log('tt:', tt)
        if (tt > 0) {
          let timer1 = Math.floor(tt / 1000)
          if (timer1) {
            this._mt = setInterval(() => {
              timer1 -= 1
              // console.log('timer1:', timer1)
              this.m = dateFormat(timer1)
              if (timer1 <= 0) {
                // 自动提交
                this.isAutoSubmit = false
                clearInterval(this._mt)
                this.autoCloseExam()
                // this.handlerClickSubmitExam()
              }
            }, 1000)
          }
        }
      },
      /**
       * 自动关闭考试
       */
      autoCloseExam() {
        window.mtAutoCloseExam = setTimeout(() => {
          this.handlerClickSubmitExam()
        }, 1000 * 60 * 10)
      },
      /**
       * 检查是否可以提交
       * @private
       */
      _chkSibmit() {
        let t1 = this.examBeginTime
        let t2 = t1 + (this.minSubmitDate * 60 * 1000)
        let tt = t2 - this.currentServerTime
        let mt = null
        if (tt > 0) {
          let timer1 = Math.floor(tt / 1000)
          countdown(mt, (_mt) => {
            timer1 -= 1
            this.m2 = dateFormat(timer1)
            if (timer1 <= 0) {
              this.isStumit = true
              clearInterval(_mt)
            }
          })
        } else {
          this.isStumit = true
        }
      },
      /**
       * 登录提示
       * @param text
       * @param lock
       * @returns {*}
       */
      loadingTools(text, lock = true) {
        return this.$loading({
          lock,
          text,
          spinner: 'el-icon-loading',
          background: 'rgba(255, 255, 255, 0.4)'
        })
      },
      /**
       * 检查登录状态
       */
      _checkTime() {
        this._closeCheckTime()
        const timeArr = [2, 4, 6]
        if (timeArr.indexOf(this.chkCnt) > -1) {
          this.gatherScreen()
        }
        this.chkCnt += 1
        console.log('chkCnt', this.chkCnt)
        window.mtCheckTime = this.$http.get(this.examingCheckTime)
          .then(res => {
            setTimeout(() => {
              this._checkTime()
            }, 1000 * 60 * 10)
          })
      },
      /**
       * 关闭定时请求
       */
      _closeCheckTime() {
        clearTimeout(window.mtCheckTime)
      },
      gatherScreen() {
        const desktopCapturer = Electrom.desktopCapturer
        const thumbSize = this.screenShotSize
        const options = {types: ['screen'], thumbnailSize: thumbSize}
        desktopCapturer.getSources(options, (error, sources) => {
          if (error) return console.log(error)
          const CurrentDate = new Date().getTime()
          let i = 1
          sources.forEach((source) => {
            const fileName = `${this.stuInfo.examId}-${this.stuInfo.loginName}-${CurrentDate}-${i}.png`
            const screenshotPath = `${__static}\\screen\\${fileName}`
            let error = fs.writeFileSync(screenshotPath, source.thumbnail.toPNG())
            if (error) return console.log(error)
            i += 1
            this.ftpFileUpload(screenshotPath, `\\screen\\${fileName}`)
          })
        })
      }
    },
    computed: {
      ...mapGetters(['screenShotSize']),
      /***
       * 文件总大小 M
       */
      uploadFileSizeCount() {
        let cnt = 0
        this.uploadFileList.forEach(e => {
          console.log(e.size)
          cnt += e.size
        })
        return (cnt)
      },
      /**
       * 上传文件最大限制
       * @returns {number}
       */
      uploadFileMaxSize() {
        return (this.baseSize * this.fileCountMaxSize)
      },
      checkFileSize() {
        return this.uploadFileMaxSize >= this.uploadFileSizeCount
      },
      fileListComplete() {
        let flag = false
        if (this.uploadFileList.length) {
          flag = true
        }
        return flag
      },
      timerClass() {
        return (this.m.hh === 0 && this.m.mm < 5) ? 'warning' : ''
      },
      examTimer() {
        let strHH = this.m.hh > 0 ? this.m.hh + ':' : '00:'
        let strMM = this.m.mm > 0 ? this.m.mm + ':' : '00:'
        let strSS = this.m.ss > 0 ? this.m.ss + '' : '00'
        let str = strHH + strMM + strSS
        return str.length > 0 ? str : null
      },
      ts() {
        let strMM = this.m2.mm > 0 ? this.m2.mm + '分' : ''
        let strSS = this.m2.ss > 0 ? this.m2.ss + '秒' : ''
        let str = strMM + strSS
        return str.length > 0 ? str + '后可以' : null
//          return ''
      }
    }
  }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  .upload-w
    border-bottom 1px solid #DCDFE6
    margin-bottom 8px
    padding-bottom 4px

  .tip-txt
    color #ff0000
    font-size 14px

  .timer
    width 280px
    margin-left -140px
    text-align center
    background #ffffff
    z-index 999
    position relative
    left 50%
    box-shadow 0 1px 12px 1px rgba(0, 0, 0, .5)
    border-radius 0 0 5px 5px
    display flex
    padding 12px 0
    align-items center
    justify-content center
    color #555555
    border 1px solid #555555
    border-top none
    transition all linear .5s

    &.warning
      background-color #f56c6c
      border-color #c71d1d
      color #ffffff
      box-shadow 0 1px 12px 1px rgba(195, 29, 29, 0.5)
      text-shadow 1px 1px 1px rgb(93, 0, 0)

    .timer-mn
      display flex
      align-items center

    .mit
      font-size 18px

    .mxt
      flex 1
      font-size 36px

  .question-w
    display flex
    flex-direction column
    width 1005px
    height 665px
    padding 0 23px
    background-color #ffffff
    margin 19px auto 0
    overflow hidden

    .tip
      text-align right
      color #ff0000
      font-size 12px
      margin-top 15px

    .ctx
      .tt
        font-size 14px
        color #000000
        line-height 23px

      .ds
        display flex

        .cnt
          flex 1
          color #ff0000
          font-size 18px
          line-height 32px

        .sl
          text-align left
          color #666666
          min-width 200px

          .name
            margin-top 8px
            font-size 14px

          .card
            margin-top 18px
            font-size 14px

          span
            margin-left 8px
            font-size 20px
            color #000000

    .main
      display flex
      flex 1
      flex-direction column
      background-color #e3fce3
      border-radius 4px
      height 395px
      margin-top 17px
      padding 17px

      .c
        font-size 16px
        line-height 28px
        display flex
        flex 1
        flex-direction column

        .tt
          font-size 18px
          line-height 30px
          font-weight bold

        .c-a
          font-size 18px

        .c-c
          display flex
          flex 1
          flex-direction column
          overflow auto

          .c-c-1
            color #ff0000

      .btn-w
        text-align center

      .exam-btn
        text-align center
        cursor default
        font-size 16px
        width 150px
        height 30px
        line-height 30px
        margin-right 64px
        user-select: none

        &.active
          cursor pointer

        &.material.active
          background-color #57d454

        &.app.active
          background-color #00a0ec

        &.project.active
          background-color #E6A23C

        &.stumit
          cursor not-allowed
          position relative

          span
            font-size 12px

          .ipt-file
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display none

        &.stumit.active
          background-color #fc6667
          cursor default

          .ipt-file
            cursor pointer
            display block
            opacity: 0
</style>
<style lang="stylus" rel="stylesheet/stylus">
  .upload-demo
    .el-upload-list
      display flex
      margin 4px -4px 0

      .el-upload-list__item
        width 25%
        display inline-block
        margin 4px
        box-sizing border-box
        padding 10px
        border 1px solid #DCDFE6
        background-color white
</style>
